//
//  Event.swift
//  Utility
//
//  Created by 何海涛 on 2017/5/24.
//  Copyright © 2017年 何海涛. All rights reserved.
//

import Foundation

/// 示例，一套协议多套实现:
///
///     @objc protocol IEventHandlerProtocol {
///         func doSth() { ... }
///     }
///     class ConcretAEventHandler: IEventHandlerProtocol { ... }
///     class ConcretBEventHandler: IEventHandlerProtocol { ... }
///
/// 以前的做法:
///
///     class SomeUIViewController: UIViewController {
///         // 我们仅能在此保存一个实例
///         (weak) var delegate: IEventHandlerProtocol?
///         func trigger() {
///             delegate?.doSth()
///         }
///     }
///
/// 现在在做法:
///
///     class SomeUIViewController: UIViewController, IEventHandlerProtocol {
///         // cann't declare with `let`, or else `add/remove` is forbidden.
///         var events = Event<IEventHandlerProtocol>()
///         func eventInit() {
///             events += ConcretAEventHandler()
///             events += ConcretBEventHandler()
///             events +=? self // 添加弱引用
///         }
///         func trigger() {
///             // 多播.
///             events.invoke({ $0.doSth() })
///         }
///         func doSth() {
///             // self implement.
///         }
///     }
public struct Event<THandler: AnyObject>: IEvent {
    
    public typealias Handler = THandler
    
    public var container: WeakableContainer<THandler> = WeakableContainer()
    
    public init() { }
}

//@objc protocol IEventDemo {
//    func test()
//}
//class EventDemoA : IEventDemo {
//    func test() {
//        print("EventDemoA")
//    }
//}
//class EventDemoB : IEventDemo {
//    func test() {
//        print("EventDemoB")
//    }
//}
//public class EventDemo : IEventDemo {
//    
//    public init() { }
//    
//    public func run() {
//        //let events = Event<IEventDemo>()
//        //events += EventDemoA() // can not add.
//        
//        var events = Event<IEventDemo>()
//        events += EventDemoA()
//        events += EventDemoB()
//        events +=? self // 加弱引用
//        events.invoke { (handler) in
//            handler.test()
//            // print "EventDemoA" "EventDemoB" "EventDemo"
//        }
//    }
//    
//    func test() {
//        print("EventDemo")
//    }
//}
